package net.sppan.blog.interceptor;

import java.util.HashMap;
import java.util.Map;

import net.sppan.blog.annotation.Logical;
import net.sppan.blog.annotation.RequiresPermissions;
import net.sppan.blog.directive.PermissionDirective;
import net.sppan.blog.holder.ThreadLocalHolder;
import net.sppan.blog.model.User;
import net.sppan.blog.utils.WebUtils;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;

/**
 * 权限拦截器
 */
public class AuthorityInterceptor implements Interceptor {

	public void intercept(Invocation inv) {
		Controller controller = inv.getController();
		//添加资源获取钩子,提供给
		Map<String, Object> resourceMap = new HashMap<String, Object>();
		resourceMap.put(ThreadLocalHolder._REQUEST, controller.getRequest());
		resourceMap.put(ThreadLocalHolder._RESPONSE, controller.getResponse());
		ThreadLocalHolder.local.set(resourceMap);
		
		//获取方法上的权限注解
		RequiresPermissions requiresPermissions = inv.getMethod().getAnnotation(RequiresPermissions.class);
		boolean hasPermissions = true;
		//如果方法上没有权限控制，则使用controller的权限控制
		if (requiresPermissions == null) {
			requiresPermissions = controller.getClass().getAnnotation(RequiresPermissions.class);
		}
		if (requiresPermissions != null) {
			try {

				//为模版设置hasperm权限标签
				controller.setAttr("hasperm", new PermissionDirective());
				
				User sysUser = WebUtils.currentUser(controller);
				if (sysUser == null) {// 没有登陆
					hasPermissions = false;
					//把没有权限的url一起带到登录url上面
					if (StrKit.notBlank(inv.getActionKey()) && !inv.getActionKey().equals("/")) {
						controller.redirect("/admin/login_page?url=" + inv.getActionKey());
						return;
					} else {
						controller.redirect("/admin/login_page");
						return;
					}
				} else {
					// 判断是否有该资源的访问权限
					String[] values = requiresPermissions.key();
					if (values.length == 1) {
						// 如果用户没有权限，
						if (!sysUser.getPermissionSets().contains(values[0])) {
							hasPermissions = false;
							controller.renderJson("没有权限");
						}
					} else {
						if (requiresPermissions.logical().equals(Logical.AND)) {
							for (String value : values) {
								if (!sysUser.getPermissionSets().contains(value)) {
									hasPermissions = false;
									break;
								}
							}
						} else {
							hasPermissions = false;
							for (String value : values) {
								if (sysUser.getPermissionSets().contains(value)) {
									hasPermissions = true;
									break;
								}
							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (hasPermissions) {
			inv.invoke();
		}
	}
}
